{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "先导入库cv2",
   "id": "d140dec72509945e"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-18T07:49:04.100561Z",
     "start_time": "2025-01-18T07:49:04.096560Z"
    }
   },
   "cell_type": "code",
   "source": "import cv2 as cv",
   "id": "42da9dfa1b43b061",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "在opencv中，使用cv.imread()来读取图像,(im意为image)\n",
    "参数：\n",
    "* 字符串: 图像的路径\n",
    "* 枚举: 加载图像的模式 ，默认为1 ， 0 1 2分别是\n",
    "    * cv.IMREAD_GRAYSCALE：以灰度模式加载图像\n",
    "    * cv.IMREAD_COLOR： 加载彩色图像。任何图像的透明度都会被忽视。它是默认标志。\n",
    "    * cv.IMREAD_UNCHANGED：加载图像，包括alpha通道\n",
    "如果传入其他整数，则视为2\n",
    "  \n",
    "返回值: \n",
    "* numpy.array 表示这个图像的numpy数组\n",
    "* (仅在加载错误)None ，在图像加载错误时不报错，而是返回None  \n",
    "\n",
    "\n",
    "\n",
    "使用cv.show()来显示图像\n",
    "参数：\n",
    "\n",
    "* 窗口名称: 字符串类型，表示显示图像的窗口名称。\n",
    "* 图像数据: 要显示的图像，通常是一个 NumPy 数组，表示图像数据。\n",
    "\n",
    "返回值：\n",
    "\n",
    "* 无返回值: 该函数直接显示图像，窗口会持续显示，直到用户手动关闭窗口。  \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "使用*cv.waitKey()*来检测键盘\n",
    "参数: \n",
    "    * 数字，等待的时间；特别地，如果传入0，则等待无限长的时间\n",
    "文档上说：如果使用的是64位计算机，则必须k = cv.waitKey(0)按如下所示修改行：k = cv.waitKey(0) & 0xFF\n",
    "但是在我的电脑(cpu:R9 7945hx python12 opencv4.10.0)上试了，不加这个也没区别  \n",
    "\n",
    "\n",
    "\n",
    "cv.destroyAllWindows()和cv.destroyWindow()\n",
    "前者是销毁所有窗口(opencv的)，后者是传入窗口名，销毁特定窗口  \n",
    "\n",
    "下面是一段简单的演示程序\n",
    "\n",
    "*提示：如果你是通过pycharm来使用jupyter，请在启动pycharm时，以管理员身份运行，以避免pycharm因权限不足无法安装和启动jupyter*"
   ],
   "id": "bd4b40960a343405"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "#读取图像，并显示\n",
    "import cv2 as cv\n",
    "img_path=r\"img\\Earl_William.jpg\"\n",
    "img=cv.imread(img_path,1)\n",
    "cv.imshow('img',img)\n",
    "cv.waitKey(0)\n",
    "cv.destroyAllWindows()"
   ],
   "id": "86a4f92812cac501",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "使用cv.imwrite()来保存图像\n",
    "参数: \n",
    "* 保存图像的路径，类型是字符串\n",
    "* 存储图像的数组，类型是numpy.ndarray\n",
    "\n",
    "返回值\n",
    "* 保存是否成功，类型是布尔值\n",
    "  \n",
    "<br>\n",
    "在python中，通常使用matplotlib库来绘图  \n",
    "\n",
    "`mat意为矩阵(Matrix)，plot意为绘制，lib则表示库(library)`\n",
    "\n",
    "matplotlib与opencv同样使用numpy.ndarray存储图像，但是不同之处在于，opencv使用BGR存储图像，而matplotlib使用RGB存储图像\n",
    "\n",
    "借此机会，可以细说它们是如何使用numpy.ndarray存储图像的"
   ],
   "id": "c970eb25a9f79fe6"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-18T11:59:49.106786Z",
     "start_time": "2025-01-18T11:59:49.096329Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import cv2 as cv\n",
    "img_path=r\"img\\Earl_William.jpg\"\n",
    "img=cv.imread(img_path,1)\n",
    "\n",
    "print(type(img)) # <class 'numpy.ndarray'>\n",
    "print(img.shape) #通过ndarry的成员方法，可以返回它的形状信息，输出结果为(587, 450, 3),说明它的行数为587，列数为450，而每一个元素都是一个三个元素的数组，实际上这个数组就是一个像素点\n",
    "print(img[0][0]) #我们可以输出0行0列上的像素点，输出结果为[210 204 197]，这表示它的BGR三个通道的信息分别是210,204,197"
   ],
   "id": "8e78bd6c398aacfe",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "(587, 450, 3)\n",
      "[210 204 197]\n"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "而在matplotlib中，不同之处就在于，每个像素点的数组的三个元素依次为RGB\n",
    "例如，[210 204 197] 这个像素点\n",
    "* 在opencv中，会被认为是B:210 G:204 R:197\n",
    "* 在matplotlib中，会被认为是R:210 G:204 B:197\n",
    "因此，在同时使用这两个库的时候，需要对图像操作后才能使用\n",
    "\n",
    "对于这一问题，有三种解决方法\n",
    "1. 使用 NumPy 索引翻转颜色通道\n",
    "```\n",
    "img2=img[:,:,::-1]\n",
    "```\n",
    "这是numpy的切片语法，前两个`:`表示前两个维度不动  \n",
    "后面的::-1表示将第三个维度的这个三元数组倒转，使得RGB变为BGR(或BGR变为RGB)  \n",
    "据说由于numpy对数组操作的优化，使得这种方法性能较优\n",
    "\n",
    "\n",
    "2. 使用 `cv2.cvtColor` 函数和 `cv2.COLOR_BGR2RGB` 标志\n",
    "```\n",
    "img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n",
    "```\n",
    "不必多言，还有个`cv2.COLOR_RGB2BGR`\n",
    "实际上`cv2.COLOR_RGB2BGR`和`cv2.COLOR_BGR2RGB`对图像的操作都是把每个像素点的R和B对调，所以即使使用BGR2RGB，也能把RGB图像转为BGR。但是不建议这样做，以免让以后读代码的人产生困惑。\n",
    "  \n",
    "不信可以试试运行下面的代码"
   ],
   "id": "dfd66b3f86d88dd5"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-18T15:06:24.698117Z",
     "start_time": "2025-01-18T15:06:18.440500Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import cv2 as cv\n",
    "img_path=r\"img\\Earl_William.jpg\"\n",
    "img=cv.imread(img_path,1)\n",
    "img1=cv.cvtColor(img,cv.COLOR_BGR2RGB)\n",
    "img2=cv.cvtColor(img1,cv.COLOR_BGR2RGB)\n",
    "cv.imshow('img',img)\n",
    "cv.imshow('img1',img1)\n",
    "cv.imshow('img2',img2)\n",
    "cv.waitKey(0)\n",
    "cv.destroyAllWindows()"
   ],
   "id": "5dc97e16a36edaa5",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "3. 重载cv2.imshow()\n",
    "```\n",
    "cv.imshow = lambda _, y: plt.imshow(y[:,:,::-1]).figure\n",
    "```\n"
   ],
   "id": "fb39d4dcea0a02dd"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import cv2 as cv\n",
    "\n",
    "img_path=r\"img\\Earl_William.jpg\"\n",
    "cv.imshow = lambda _, y: plt.imshow(y[:,:,::-1]).figure\n",
    "img=cv.imread(img_path,1)\n",
    "plt.imshow(img)\n",
    "cv.imshow('img',img)"
   ],
   "id": "feddc8a12c542ce",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "总结：\n",
    "1. 使用img=cv.imread('path')读取图像\n",
    "2. 使用cv.imshow('win_name',img)显示图像\n",
    "3. 使用cv.waitKey(0)来阻断程序\n",
    "4. 使用cv.destroyAllWindows()来销毁所有窗口\n",
    "5. 使用cv.cvtColor(img,cv.COLOR_BGR2RGB)来转换图像格式\n",
    "6. 使用img2=img[:,:,::-1]来转换图像格式"
   ],
   "id": "71ce22b7a0c611d"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
